#!/usr/bin/python

__all__ = ["get_clipboard"]

try:
	import win32clipboard
except: pass

try:
	from Carbon.Scrap import GetCurrentScrap, ClearCurrentScrap
	import MacOS
except: pass

try:
	import pygtk
	pygtk.require('2.0')
	import gtk
except: pass

import os

try:
	import wx
except: pass

try:
	from Tkinter import Tk
except: pass

class Clipboard:
	def __init__(self, supported = False):
		self.isSupported = supported

	def get(self):
		return ""

	def set(self, text):
		pass

# not tested
class Win32Clipboard(Clipboard):
	def __init__(self):
		Clipboard.__init__(self, True)
		#self.clip_type = win32clipboard.CF_TEXT
		self.clip_type = win32clipboard.CF_UNICODETEXT

	def get(self):
		win32clipboard.OpenClipboard() 
		d = win32clipboard.GetClipboardData(self.clip_type)
		win32clipboard.CloseClipboard() 
		return d 
 
	def set(self, text):
		win32clipboard.OpenClipboard()
		win32clipboard.EmptyClipboard()
		win32clipboard.SetClipboardData(self.clip_type, text)
		win32clipboard.CloseClipboard()

# not tested
class MacClipboard(Clipboard):
	def __init__(self):
		Clipboard.__init__(self, True)

	def get(self):
		try:
			scrap = GetCurrentScrap()
			return scrap.GetScrapFlavorData('TEXT')
		except MacOS.Error, e:
			if e[0] != -102:
				# -102 == noTypeErr
				raise
			return ""
 
	def set(self, text):
		ClearCurrentScrap()
		scrap = GetCurrentScrap()
		scrap.PutScrapFlavor('TEXT', 0, text)

# not tested
class PygtkClipboard(Clipboard):
	def __init__(self):
		Clipboard.__init__(self, True)
		self.text = ''

	def __callback(self, clipboard, text, data):
		if not text or text == '':
			return
		self.text = text

	def get(self):
		clipboard = gtk.clipboard_get()
		clipboard.request_text(self.__callback)
		return self.text
 
	def set(self, text):
		clipboard = gtk.clipboard_get()
		clipboard.set_text(text)
		# make our data available to other applications
		clipboard.store()

# not tested
class XClipboard(Clipboard):
	def __init__(self):
		Clipboard.__init__(self, True)

	def get(self):
		return os.popen('xsel').read()
 
	def set(self, text):
		os.popen('xsel', 'wb').write(text)

# TODO: broken
class TkinterClipboard(Clipboard):
	def __init__(self):
		Clipboard.__init__(self, True)
		self.root = Tk()
		self.root.withdraw()

	def get(self):
		return self.root.tk.call(('clipboard', 'get'))
 
	def set(self, text):
		self.root.tk.call(('clipboard', 'clear'))
		self.root.tk.call(('clipboard', 'append', text))

# not tested
class wxClipboard(Clipboard):
	def __init__(self):
		Clipboard.__init__(self, True)

	def get(self):
		if wx.TheClipboard.Open():
			data = wx.TextDataObject()
			success = wx.TheClipboard.GetData(data)
			wx.TheClipboard.Close()
			return data.GetText()
		return ""
 
	def set(self, text):
		if wx.TheClipboard.Open():
			data = wx.TextDataObject(text)
			wx.TheClipboard.SetData(data)
			ex.TheClipboard.Close()

def get_clipboard():
	if 'win32clipboard' in dir():
		return Win32Clipboard()

	if 'GetCurrentScrap' in dir():
		return MacClipboard()

	if os.system('xsel -v') == 0:
		return XClipboard()

	if 'gtk' in dir():
		return PygtkClipboard()

	if 'Tk' in dir():
		return TkinterClipboard()

	if 'wx' in dir():
		return wxClipboard()

	return Clipboard()

if __name__ == "__main__":
	clip = get_clipboard()
	clip.set("123")
	print "data: '%s' (%d)" % (clip.get(), len(clip.get()))
